import { calcDPR } from '@amcax/base';
import {
  caeWarnLog,
  drawColorMap,
  getColorMap,
  ModelEventType,
  toScientificValue,
  userEvents,
} from 'nextcae-base';
import { useEffect, useRef, useState } from 'react';

/**
 * 绘制尺度条
 * @param count 尺度条刻度数量
 * @param canvas 画布
 */
const drawRule = (count: number, canvas: HTMLCanvasElement) => {
  const width = canvas.width, // 画布宽度
    height = canvas.height; // 画布高度
  const ctx = canvas.getContext('2d'); // 获取2D绘图上下文
  const scaleWidth = width / 2; // 尺度条宽度，剩下一半用于colorbar
  const scaleHeight = 1 * calcDPR(); // 根据设备像素比计算尺度条高度
  ctx.strokeStyle = '#fff'; // 设置刻度线颜色为白色
  ctx.beginPath(); // 开始绘制路径
  for (let i = 0; i <= count; i++) {
    let y = (i * height) / count, // 计算每个刻度的Y坐标
      w = 0, // 刻度线宽度
      h = 0; // 刻度线高度
    if (i % 10 === 0) {
      w = scaleWidth; // 每10个刻度显示完整宽度
      h = scaleHeight;
      if (i === count) {
        // 最后一个刻度向上偏移一个scaleHeight
        y -= scaleHeight;
      }
    } else if (i % 5 === 0) {
      // 每5个刻度显示3/4宽度
      w = (scaleWidth * 3) / 4;
      h = scaleHeight / 2;
    } else {
      // 其他刻度显示1/2宽度
      w = scaleWidth / 2;
      h = scaleHeight / 4;
    }
    ctx.fillStyle = 'white'; // 设置填充颜色为白色
    ctx.fillRect(width / 2, y, w, h); // 绘制刻度矩形
  }
};

type IExtra = { min: number; max: number }; // 定义额外数据类型，包括最小值和最大值

// 处理刻度尺精度现保留2位有效小数
const ColorScaleSpan = ({
  value,
  flex = 1,
}: {
  value: number;
  flex?: number;
}) => {
  const num = toScientificValue(value, 10);
  const valueNum = parseFloat(num);
  if (isNaN(valueNum)) caeWarnLog('请求结果错误:', valueNum);
  const result = valueNum.toExponential(1).replace(/(\d+\.\d)e/, '$1e'); // 保留两位有效数字
  return <span style={{ flex }}>{result}</span>; // 以科学计数法显示值，保留2位有效小数
};

const ColorScale = ({ extra }: { extra?: IExtra }) => {
  if (!extra) {
    return <></>; // 如果没有额外数据，则返回空
  }
  // 使用原始最小值和最大值，顶部为最小值（红色），底部为最大值（蓝色）
  const { min, max } = extra;
  return (
    <div
      style={{
        display: 'flex',
        marginLeft: '5px',
        flexDirection: 'column', // 正常列方向
        justifyContent: 'space-between',
        alignItems: 'start',
        height: '320px',
        color: '#000',
      }}>
      <ColorScaleSpan value={max} /> {/* 显示顶部最大值（红色） */}
      <ColorScaleSpan value={(max + min) / 2} /> {/* 显示中间值 */}
      <ColorScaleSpan
        value={min}
        flex={0}
      />{' '}
      {/* 显示底部最小值（蓝色） */}
    </div>
  );
};

export default function ColorScaleBar() {
  const canvasRef = useRef<HTMLCanvasElement>(null); // 引用canvas元素
  const [colormap, setColormap] = useState<string>(null); // 存储颜色映射
  const [extra, setExtra] = useState<IExtra>(null); // 存储额外数据
  const rightPosition = 10; // 右侧位置偏移量

  useEffect(() => {
    // 监听事件以更新颜色映射和额外数据
    userEvents.on(ModelEventType.SetColormap, handleSetColormap);
    userEvents.on(ModelEventType.SetExtra, handleSetExtra);
    userEvents.on(ModelEventType.ResetColorbar, () => {
      setColormap(null); // 重置颜色映射
      setExtra(null); // 重置额外数据
    });
    return () => {
      // 清理事件监听
      userEvents.off(ModelEventType.SetColormap);
      userEvents.off(ModelEventType.SetExtra);
      userEvents.off(ModelEventType.ResetColorbar);
    };
  }, []);

  useEffect(() => {
    if (canvasRef.current) {
      const n = 20; // 刻度数量
      drawRule(n, canvasRef.current); // 绘制刻度条
      if (colormap) {
        const colorMap = getColorMap(colormap, n); // 获取颜色映射
        // 反转颜色映射以从顶部（最小值，红色）到底部（最大值，蓝色）绘制
        drawColorMap(
          colorMap.reverse(),
          colorMap.length,
          canvasRef.current,
          'vertically',
        );
      }
    }
  }, [canvasRef.current, colormap]); // 依赖canvas和colormap更新

  const handleSetColormap = (colormap: string) => {
    setColormap(colormap); // 更新颜色映射
  };

  const handleSetExtra = (extra: IExtra) => {
    if (extra.min !== undefined && extra.max !== undefined) {
      setExtra({ min: extra.min, max: extra.max }); // 使用原始顺序
    }
  };

  if (colormap == null) {
    return <></>; // 如果没有颜色映射，返回空
  }

  return (
    <div
      style={{
        position: 'absolute',
        marginBottom: '10px',
        top: '50%',
        transform: 'translateY(-50%)',
        right: `${rightPosition + 10}px`,
      }}>
      <div
        style={{
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}>
        <canvas
          ref={canvasRef}
          style={{ width: '30px', height: '300px' }}
        />{' '}
        {/* 绘制canvas */}
        <ColorScale extra={extra} /> {/* 渲染颜色刻度 */}
      </div>
    </div>
  );
}
